package 
{
import com.bit101.components.*;
import com.duobiduo.audio.*;
import com.duobiduo.audio.filters.TDSI.PitchFilter;
import com.duobiduo.audio.stream.*;

import de.popforge.audio.output.Audio;
import de.popforge.audio.output.AudioBuffer;
import de.popforge.audio.output.Sample;
import de.popforge.audio.output.SoundFactory;
import de.popforge.audio.processor.effects.BasicFilter;
import de.popforge.format.wav.WavFormat;
import de.popforge.parameter.MappingNumberLinear;
import de.popforge.parameter.Parameter;

import flash.display.Sprite;
import flash.events.ActivityEvent;
import flash.events.Event;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.*;

import org.as3wavsound.WavSound;
import org.bytearray.micrecorder.MicRecorder;
import org.bytearray.micrecorder.encoder.WaveEncoder;
import org.bytearray.micrecorder.events.RecordingEvent;

/**
 * ...
 * @author efishocean, www.duobiduo.com
 */
[SWF(width=320,height=240)]
public class Test extends Sprite 
{
    private var recorder:MicRecorder;
    //回播
    private var soundPlayer:WavSound;
    
    private var wav: WavFormat;    
    private var phase: Number;    
    private var filter: BasicFilter;    
    private var audio:AudioXStream;
    private var chanel:AudioChannelX;
    private var length:Number = 0;
    private var pitchFilter:PitchFilter;
    
    private var parameterPitch: Parameter;  
    public function Test():void 
    {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }
    
    private function init(e:Event = null):void 
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        // entry point
        recorder = new MicRecorder(new WaveEncoder(), null, 100, 44, 30, 100);
        recorder.addEventListener(RecordingEvent.RECORDING, recordingHandler);
        recorder.addEventListener(Event.COMPLETE, recordCompleteHandler);
        recorder.record();
        recorder.microphone.addEventListener(ActivityEvent.ACTIVITY, microActivityHandler);
        
        parameterPitch = new Parameter( new MappingNumberLinear( -1, 3 ), 1 );    
        
        filter = new BasicFilter();   
    }
    //==========================================================================
    //  Event Handlers
    //==========================================================================
    private function recordingHandler(event:RecordingEvent):void
    {
        //                player.doAction("20101");
    }
    
    private function recordCompleteHandler(event:Event):void
    {
        soundPlayer = new WavSound(recorder.output);
        //        soundPlayer.play();
        recorder.record();
        //        SoundFactory.fromByteArray(recorder.output,Audio.MONO,Audio.BIT16,Audio.RATE44100,onOk); 
        wav = WavFormat.decode(recorder.output);   
        initAudioEngine();
    }
    
    private function onOk(event:Sound):void
    {
        var _channel:SoundChannel;
        _channel = event.play();    
        _channel.addEventListener(Event.SOUND_COMPLETE,onSoundComplete);    
    }
    
    private function onSoundComplete(evt:Event):void    
    {    
        trace("good");    
    }   
    
    private function initAudioEngine(): void    
    {    
        var buffer: AudioBuffer = new AudioBuffer( 4, Audio.STEREO, Audio.BIT16, Audio.RATE44100 );    
        buffer.onInit = onAudioBufferInit;    
        buffer.onComplete = onAudioBufferComplete;    
        
        phase = 0;
    }    
    
    private function onAudioBufferInit( buffer: AudioBuffer ): void    
    {    
        buffer.start();    
    }  
    
    private function onAudioBufferComplete( buffer: AudioBuffer ): void    
    {    
        //-- get array to store samples    
        var samples: Array = buffer.getSamples();    
        
        //-- some locals    
        var output: Sample;    
        var input: Sample;    
        
        //-- compute speed    
        var speed: Number = wav.rate / buffer.getRate() * parameterPitch.getValue();    
        
        //-- CREATE ONE SECOND OF AUDIO (SINUS WAVE)    
        for( var i: int = 0 ; i < samples.length ; i++ )    
        {    
            //-- store local    
            output = samples[i];    
            input = wav.samples[ int( phase ) ];    
            
            //-- write to sample    
            output.left = input.left;    
            output.right = input.right;    
            
            //-- move pointer    
            phase += speed;    
            
            if( phase < 0 )    
                phase += wav.samples.length;    
            else if( phase >= wav.samples.length )    
                phase -= wav.samples.length;    
        }    
        
        filter.processAudio( samples );    
        
        //-- update audio buffer    
        buffer.update();  
        
        //        SoundFactory.fromByteArray(recorder.output,Audio.MONO,Audio.BIT16,Audio.RATE44100,onOk); 
    }    
    
    private function microActivityHandler(event:ActivityEvent):void
    {
        trace(event.activating);
        if (event.activating)
        {
            //
        }
        else
        {
            recorder.stop();
        }
    }
    
    private function soundCompleteHandler(event:Event):void
    {
        recorder.record();
        trace("record");
    }
}
}